#! /usr/bin/env python
# -*- coding: utf-8 -*-
"""South Africa data format
Copyright (c) 2011-2014 Christian T. Steigies <steigies@physik.uni-kiel.de>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.

This module offers functions to read NM data in CSV format as used in South Africa
and return data in the format as used by NMDB.
The CSV files are (symlinked) in ~/data/south_africa/STATION/[1h|ori|rev]
"""

__author__ = "Christian T. Steigies <steigies@physik.uni-kiel.de>"
__license__ = "GPL License"

import os
from datetime import datetime
#import urllib2

from nmdb.station.station_data import check_data, check_pressure
#from nmdb.tools.configtool import parse_config
from nmdb.tools.datetool import doy2date, valid_date
from nmdb.tools.pressure import mbar

south_africa_station = ["tsmb", "hrms", "ptfm", "snae", "sanb"]
south_africa_longnames = {"tsmb": "Tsumeb",
                          "hrms": "Hermanus",
                          "ptfm": "Potchefstroom",
                          "snae": "Sanae",
                          "sanb": "Sanae bare"}

## --------------------------------------------------------------------------
def read_rt(options, station, data_type, year, month, day):
    """read realtime data

    options     verbose, dryrun, ...
    station     station short name, must be valid station
    data_type   "1m", "1h", "env", "meta"
    year        integer (1950-9999), may not be None
    month       integer (1-12), if None, read month 1-12
    day         integer (1-31), if None, read day 1-31

    return list of values in nmdb format
    """

    if station in south_africa_station:
        pass
    else:
        raise ValueError  # wrong station

    value = []
    if valid_date(year, month, day):
        value = read_za_rt(options, station, data_type, year, month, day)

    return value

## --------------------------------------------------------------------------
def read_rev(options, station, data_type, year, month, day):
    """read revised data

    options     verbose, dryrun, ...
    station     station short name, must be valid station
    data_type   "1m", "1h", "env", "meta"
    year        integer (1950-9999), may not be None
    month       integer (1-12), if None, read month 1-12
    day         integer (1-31), if None, read day 1-31

    return list of values in nmdb format
    """

    if station in south_africa_station:
        pass
    else:
        raise ValueError  # wrong station

    value = []
    if valid_date(year, month, day):
        value = read_za_rev(options, station, data_type, year, month, day)

    return value

## --------------------------------------------------------------------------
def read_za_rev(options, station, data_type, year, month, day):

    if station in south_africa_station:
        pressure = [800., 1200.]
        countrate = [1., 100000.]
    else:
        raise ValueError  # wrong station

    if data_type in ["1m", "1h"]:
        value = read_csv(options, station, data_type, year, month, day)
    elif data_type in ["env", "meta"]:
        value = []
    else:
        raise ValueError  # illegal data_type

    return value
## --------------------------------------------------------------------------
def read_za_rt(options, station, data_type, year, month, day):

    if station in south_africa_station:
        pressure = [800., 1200.]
        countrate = [1., 100000.]
    else:
        raise ValueError  # wrong station

    if options.verbose > 0:
        print "read_kiel:", year, month, day

    if data_type in ["1m", "1h"]:
        value = read_csv(options, station, data_type, year, month, day)
    elif data_type in ["env", "meta"]:
        value = []
    else:
        raise ValueError  # illegal data_type

    return value

## --------------------------------------------------------------------------
def read_csv(options, station, data_type, year=None, month=None, day=None):
    """Year, Day[1-366], Hour[0-23], Corrected counts/ 100,Pressure x 10 mm Hg,Uncorrected/100
    """
    
    data = []    
    data_path = '~/data/south_africa'
    data_path = os.path.expanduser(data_path)
    if data_type in ["1m", "ori", "rev"]:
        data_type = "1m"
        filename = "%s/%s/rev/%s_%04i_1m.csv" % (data_path, station, station, year)
        interval = 60  # calculate actual interval?
    elif data_type in["1h"]:
        interval = 3600  # hour data
        filename = "%s/%s/1h/%s_%04i_1h.csv" % (data_path, station, station, year)
    else:
        print "unknown data:", data_type
        return data

    try:
        myfile = open(filename, 'rb')
    except IOError:
        print "file not found", filename
        return data        

    #pos = myfile.tell()
    ## skip the first line, if it documents the file format
    #line = myfile.readline()
    #if (14 <= len(line) < 30):  # this looks like data, so scroll back
    #    myfile.seek(pos)

    line = True
    while line:
        line = myfile.readline()
        if (len(line) < 14) or (len(line) > 30):
            continue  # skip, line too short or too long for data
        row = line.split(",")
        if year and year != int(row[0]):
            continue  # skip data if year does not match
        doy = int(row[1])
        hour = int(row[2])
        try:
            corr = float(row[3])*100.
        except ValueError:
            corr = 0
        try:
            press = float(row[4])/10.
        except ValueError:
            press = 0
        try:
            ucorr = float(row[5])*100.
        except ValueError:
            ucorr = 0

        date = doy2date(int(year), int(doy))
        if month and month != date.month:
            continue  # skip data if month does not match
        if day and day != date.day:
            continue  # skip data if day does not match
        timestamp = datetime(date.year, date.month, date.day, hour, 0)
       
        corr = round(corr/interval, 3)
        press = round(mbar(press), 2)
        uncorr = round(ucorr/interval, 3)
        uncorr = check_data(uncorr, cr_min=10., cr_max=10000.)
        press = check_pressure(press, p_min=500., p_max=1100.)
        corr = check_data(corr, cr_min=10., cr_max=10000.)
        ceff = corr

        data.append([timestamp, interval, uncorr, ceff, corr, press])

    return data


## --------------------------------------------------------------------------
def main():

    import optparse
    parser = optparse.OptionParser("usage: %prog [options]")
    parser.add_option("-v", dest="verbose", default=0, action="count",
            help="increment output verbosity; may be specified multiple times")
    (options, args) = parser.parse_args()

    print "This is the south_africa module."

    station = "snae"
    data_type="1h"
    data_type="1m"
    year = 1976
    month = 1
    day = 1
    
    #data = read_rev(options, station, data_type, year, month, day)
    data = read_rt(options, station, data_type, year, month, day)
    for line in data:
        print line

## --------------------------------------------------------------------------
if __name__ == '__main__':
    main()
